#pragma once

#include "OpenGL.hpp"
#include "SuperData.h"
#include "Message.h"
#include <vector>
#include <map>
#include "State Machine.h"
#include "Timer.hpp"
#include "GLPrimitives.h"
#include "ClippingPlane.h"
#include "ImageLoader.hpp"
#include "General Structures.hpp"
using namespace std;

#define m_GameTimer Entity::GameTimer

//	The Entity class. Abstract. Any thing that is displayed on the screen will be from a class derived from this class.
//	It must be first initialized through the Init() function. To creat an entity, one must pass a string, the entity name
//	as an argument to the constructor in the declaration of the class.

class Entity
{
private:

	//static SDL_Surface* m_destination;
	static vector<GLuint> m_images;
	static vector<Dimension> m_images_sizes_orig, m_images_sizes_padded;
	static vector<string> m_images_names;
	static vector<GLuint> m_displayLists;
	static int m_entityCount; // how many entities are active
	static int ignoredImage; // used for optimization
	//static map<string, int> NameToIDMap; // Used for finding the ID of a given Entity through it's name
										// NOTE: Needs to be initialized.

	// Used for zooming
	static float m_scaler;

	static float m_z; // What z level are we currently on

	// Animation
	vector<int> m_animationFrames;

	string m_BaseImg;

	int m_animationUpdate;
	Timer m_animationTimer;

protected:

	int m_animationAngle;
	float m_scale;

private:

	unsigned int m_currentFrame;
	bool m_isAnimation;
	Timer m_AnimationUpdate;


protected:

	int imageID; // An index to the image in the m_images vector for this particular entity.

	SDL_Rect Rect; // to hold the image offsets

public:
	static int GetEntityCount() {return m_entityCount;}
	static void AddAllImages();
	static void RenderImage(int x, int y, int ID, ClippingPlane* pClippingPlane); // renders the specified ID, if not valid it aborts
	// Animation
	void SetAnimationBase(string baseName, string subBaseName = "stand");
	void SetAnimationSubBase(string subBase);
	void SetNextImage();
	void ResumeAnimation() {m_isAnimation = true;}
	void StopAnimating() {m_isAnimation = false;}

	void ChangeX(int x) {Rect.x= x;}
	void ChangeY(int y) {Rect.y = y;}
	bool OnScreen(); // is the entity on the screen?

	Entity();
	Entity( string name );
	~Entity();

	static Timer GameTimer;


	static void FreeImage(int imgID);

	inline bool IsIgnoredTile() const {return (imageID == ignoredImage);}

	static void SetScaler(float level) {m_scaler = level;}
	static float GetScaler() {return m_scaler;}

	virtual inline float GetX() const {return Rect.x;}
	virtual inline float GetY() const {return Rect.y;}

	inline int GetWidth() const {return Rect.w;}
	inline int GetHeight() const {return Rect.h;}

	static inline void IncrementZLevel() {m_z += 0.05f;}
	static inline void ResetZLevel() {m_z = 0.0f;}

	void applySurface();
	void applySurface(float rotation);

	void SetRect(SDL_Rect Rectangle) {Rect = Rectangle;}
	void SetRect(GameRectangle Rectangle);

	void DrawRect();

	void SetImageID(string name) {imageID = ImageManager->GetImageID(name);  Rect.h = m_images_sizes_orig[imageID].h;	 Rect.w = m_images_sizes_orig[imageID].w;} // Sets the imageID of this particular entity from the given name.
	int ID() const {return imageID;}

	static void Init();
	static void FreeAllImages();

	bool Intersects(SDL_Rect);
	bool Intersects(GameRectangle aRect);
};
